package com.bprogram.config;

import com.bprogram.pojo.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.lang.Assert;
import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JwtUtils {
public  static  final String SECRET = "bprogram-secret";

    /**
     * 生成token
     * @param user 需要加密的用户信息
     * @param ttl 有效时间单位秒
     * @return
     */
    public static String generateToken(User user,int ttl) {
        // JWT头部分信息【Header】
        Map<String, Object> header = new HashMap<>();
        header.put("alg", "HS256");
        header.put("typ", "JWT");

        // 载核【Payload】
        Map<String, Object> payload = new HashMap<>();
        payload.put("userCode",user.getUserCode());
        payload.put("role",user.getPerms());


        // 声明Token失效时间
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND,ttl);// 单位秒
        SecretKey key = generalKey(SECRET);
        // 生成Token
        String token = Jwts.builder()
                .setHeader(header)// 设置Header
                .setClaims(payload) // 设置载核
                .setExpiration(instance.getTime())// 设置生效时间
                .signWith(SignatureAlgorithm.HS256, key) // 签名,这里采用私钥进行签名,不要泄露了自己的私钥信息
                .compact(); // 压缩生成xxx.xxx.xxx

        System.out.println("Bearer "+token);
        return "Bearer "+token;
    }

    /**
     * 根据token获取负载Claims，获取信息
     * @param token
     * @return
     */
    public static Claims getClaims(String token){
        SecretKey key = generalKey(SECRET);
            Claims claims = null;
            try {
                claims = Jwts.parser()
                        .setSigningKey(key)
                        .parseClaimsJws(token)
                        .getBody();
            }catch (SignatureException e){
                System.out.println("签名错误");
            }
            catch (Exception e) {
                Assert.isTrue(false,"JWT格式验证失败:{}"+token);
            }
            return claims;

    }

//生成jwt的密钥key
    public static SecretKey generalKey(String secret) {
        String stringKey = secret;//本地配置文件中加密的密文
        byte[] encodedKey = Base64.decodeBase64(stringKey);//本地的密码解码[B@152f6e2
        System.out.println(encodedKey);//[B@152f6e2
        System.out.println(Base64.encodeBase64URLSafeString(encodedKey));//7786df7fc3a34e26a61c034d5ec8245d
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");// 根据给定的字节数组使用AES加密算法构造一个密钥，使用 encodedKey中的始于且包含 0 到前 leng 个字节这是当然是所有。（后面的文章中马上回推出讲解Java加密和解密的一些算法）
        return key;
    }




    public static String testToken(User user) {
        // JWT头部分信息【Header】
        Map<String, Object> header = new HashMap<>();
        header.put("alg", "HS256");
        header.put("typ", "JWT");

        // 载核【Payload】
        Map<String, Object> payload = new HashMap<>();
        payload.put("userCode",user.getUserCode());
        payload.put("role",user.getPerms());



        SecretKey key = generalKey(SECRET);
        // 生成Token
        String token = Jwts.builder()
                .setHeader(header)// 设置Header
                .setClaims(payload) // 设置载核

                .signWith(SignatureAlgorithm.HS256, key) // 签名,这里采用私钥进行签名,不要泄露了自己的私钥信息
                .compact(); // 压缩生成xxx.xxx.xxx

        System.out.println("Bearer "+token);
        return "Bearer "+token;
    }
}
